<template>
    <el-card shadow="hover" class="optimized-card">
        <!-- 选择界面 -->
        <div class="header-section">
            <div class="station-info">
                <div class="info-item">
                    <span class="info-label">产线：</span>
                    <el-input disabled placeholder='DQ-TG-2' class="info-input"></el-input>
                </div>
                <div class="info-item">
                    <span class="info-label">工位：</span>
                    <el-input disabled placeholder='2-OP5010-0' class="info-input"></el-input>
                    <span class="station-tag">返修工位</span>
                </div>
                <div class="serial-control">
                    <el-button round plain type="primary" @click="openPort">连接串口</el-button>
                    <el-button round plain type="danger" @click="closePort">关闭串口</el-button>
                    <el-button class="status-indicator" :style="serialColor"></el-button>
                </div>
            </div>
        </div>

        <!-- 扫码界面 -->
        <div class="scan-section">
            <el-form class="scan-form">
                <el-form-item label="物料条码：" class="scan-item">
                    <el-input v-model="textSN" disabled class="scan-input"></el-input>
                </el-form-item>
                <el-form-item label="扫码结果：" class="scan-item">
                    <el-input v-model="SNMessage" disabled class="scan-input"></el-input>
                </el-form-item>
            </el-form>
            <div class="sn-display">返修SN: {{OldSN}}</div>
        </div>

        <el-divider class="custom-divider"></el-divider>

        <!-- 物料绑定界面 -->
        <div class="main-content">
            <div class="material-section">
                <div class="table-container">
                    <table class="enhanced-table">
                        <thead>
                            <tr>
                                <th><input type="checkbox" v-model="allSelected" @change="toggleSelectAll"/></th>
                                <th>上料工位</th>
                                <th>物料编码</th>
                                <th>物料名称</th>
                                <th>物料SN号</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(item,index) in stateInfo.AllBindings" :key="index">
                                <td><input type="checkbox" v-model="item.selected" /></td>
                                <td>{{ item.stationCode }}</td>
                                <td>{{ item.materialCode }}</td>
                                <td>{{ item.materialName }}</td>
                                <td>{{ item.AssembleSN }}</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <div class="action-buttons">
                    <el-button type="warning" @click="processSelectedItems" class="action-btn">解绑</el-button>
                    <el-button type="info" @click="toggleParttern" class="action-btn">
                        {{ScanPattern?'切换下线解绑模式':'切换单体物料解绑模式'}}
                    </el-button>
                </div>
            </div>

            <el-divider direction="vertical" class="vertical-divider"></el-divider>

            <div class="log-section">
                <h3 class="log-title">返修日志</h3>
                <ul class="log-list">
                    <li v-for="item in stateInfo.AllLogs" :class="{'error-log': item.LogType !== 'good'}">
                        {{ item.Date_Time }}: {{ item.Log }}
                    </li>
                </ul>
            </div>
        </div>
    </el-card>
</template>
<script setup lang="ts" name="返修管理">
import {ref, reactive, watch, onMounted, getCurrentInstance, defineAsyncComponent, nextTick,computed, onUnmounted} from 'vue';
import { Console } from 'console';
import axios from 'axios';
const ci = getCurrentInstance() as any;
import {  ElMessageBox, ElMessage,ElTable,ElTableColumn } from 'element-plus';
import { useRouter } from "vue-router";
import internal from 'stream';
import other from '/@/utils/other';
import request from '/@/utils/request';
import { HubConnectionBuilder } from '@microsoft/signalr';
import { text } from 'stream/consumers';
import { isRegExp } from 'util/types';




// 产线、工位选择信息
interface SelectedMessage {  
    StationCode: null | string; 
    LineCode: null | string;  
}  
const selectedMessage = ref<SelectedMessage>({  
    StationCode: null,  
    LineCode: null,  
});

// 标志位，表示是否读取到历史选择信息
const flagValue = ref<number>(0);
const virtualSN = ref<string | null>(null)
const StationName = ref('')
const sNFlag = ref<number>(0)

//串口连接状态
const serialColor = ref('background-color:red;width:30px;height:30px;margin-top:8px') 
const comeinColor = ref('background-color: gray;font-size: 25px;')
const port = ref(null);
const reader = ref(null);

//

//串口扫码数据
const textSN = ref('')
//扫码结果
const SNMessage = ref('无扫码信息')
const OldSN = ref('')

interface Dictionary {  
    [key: string]: any; // 任何类型的值  
}
//状态数据
const stateInfo = reactive({
    //产线信息
    AllLines: [] as any[],
    //工位信息
    AllStations: [] as any[],

    //工位日志信息
    AllLogs: [] as any[],       // TAG = 1
    AllBindings: [] as any[],  // TAG = 2
});


// 接受报错推送信息 
let connection: signalR.HubConnection|null = null;   

const startConnection = async () => {  //连接服务器
  try {  
    connection = new HubConnectionBuilder()  
      .withUrl("/NotificationHub")  
      //.configureLogging(signalR.LogLevel.Information)  
      .withAutomaticReconnect()
      .build();  

    connection.on("ReceiveMessage", (message) => {  //注册事件
        if(message.lineCode == selectedMessage.value.LineCode && message.stationCode == selectedMessage.value.StationCode){
            
            flushUI(selectedMessage.value.LineCode, selectedMessage.value.StationCode);
        }
    }); 
    await connection.start(); 
  } catch (err) {  
    //console.error("Error starting SignalR connection:", err);  
  }  
};  

const stopConnection = () => {  
  if (connection) {  
    try {  
      connection.stop();  
    } catch (err) {  
    }  
  }  
};  




const allSelected = ref(false);

//切换扫码模式
const ScanPattern:any = ref(false);
const toggleParttern = ()=>{
    ScanPattern.value = !ScanPattern.value
}

const testshow = ()=>{
    // request({
    //     url: 'api/RepairRecord/GetSingleRepairData',
    //     method: 'post',
    //      data: {
    //             'LineCode':selectedMessage.value.LineCode,
    //             'StationCode':selectedMessage.value.StationCode,
    //             'TZMaterialCode': '20020206-13978378-00-20240812-7054'   //电机号
    //             }
    //         }).then(res => {
    //                 stateInfo.AllBindings = res.RepairMaterialInfos,
    //                 OldSN.value = res.SN,
    //                 console.log('st',selectedMessage.value.StationCode),
    //                 flushUI(selectedMessage.value.LineCode,selectedMessage.value.StationCode)
    //         })
    if(!ScanPattern.value){
           request({
           url: 'api/RepairRecord/GetSingleRepairData',
           method: 'post',
           data: {
               'LineCode':selectedMessage.value.LineCode,
               'StationCode':selectedMessage.value.StationCode,
               'TZMaterialCode': 'TZ220XYE 3G4149096'   //电机号
           }
       }).then(res => {
           stateInfo.AllBindings = res.RepairMaterialInfos,
           OldSN.value = res.SN,
           flushUI(selectedMessage.value.LineCode,selectedMessage.value.StationCode)
       })
       }
       else{
           request({
            url: 'api/RepairRecord/LooseSingleMaterial',
            method: 'post',
            data: {
            'LineCode':selectedMessage.value.LineCode,
            'StationCode':selectedMessage.value.StationCode,
            'TZMaterialCode': 'TZ220XYE 3G4109434'   //电机号
            }
            }).then(res => {
            stateInfo.AllBindings = res.RepairMaterialInfos,
            OldSN.value = res.SN,
            flushUI(selectedMessage.value.LineCode,selectedMessage.value.StationCode)
        })
        }
}

const toggleSelectAll=()=>{
    
    stateInfo.AllBindings.forEach(item=>{
        item.selected = allSelected.value;
    })
    
}
const  processSelectedItems=()=>{
    // const selectedItems = stateInfo.AllBindings.filter(item=>item.selected);
    // console.log(selectedItems);
    request({
        url: 'api/BaseInformation/Station/BackflowUnbind',
        method: 'post',
         data: {
                'lineCode':selectedMessage.value.LineCode,
                'stationCode':selectedMessage.value.StationCode,
                'SN': OldSN.value,  //sn号
                'TZMaterialCode':virtualSN.value,  //扫上来的发动机号
                'RepairMaterialInfos':stateInfo.AllBindings
                }
            }).then(res=>{
                // 刷新界面信息
                flushUI(selectedMessage.value.LineCode, selectedMessage.value.StationCode)
            })
}



// 页面加载时
onMounted(() => {
    selectedMessage.value.LineCode='DQ-TG-2',
    selectedMessage.value.StationCode = '2-OP5010-0',
    flushUI(selectedMessage.value.LineCode, selectedMessage.value.StationCode),
    //创建signalR连接
    startConnection();
});

onUnmounted(() => {
    //断开signalR连接
    stopConnection();
});


const flushUI = (lineCode: string | null, stationCode: string | null) => {
        if(lineCode != null && stationCode != null && lineCode != '' && stationCode != '') {

            request({
                url: '/api/BaseInformation/Station/GetUiInfo',
                method: 'post',
                data: {
                    'LineCode': selectedMessage.value.LineCode,
                    'StationCode': selectedMessage.value.StationCode
                }}).then(res=>{
                    if(res.Code == '01') { //无工单信息
                        ClearInfo()
                    } else {
                        stateInfo.AllLogs = res.Logs;       //工位日志
                    }
                })

        } else {
            // 清空界面显示信息
            ClearInfo()
        }
}

const ClearInfo = () => {
    stateInfo.AllLogs = [],
    stateInfo.AllBindings = []
};

//
// 弹窗状态

//打开串口
const openPort = async () => {
    try {
        port.value = await navigator.serial.requestPort();
        await port.value.open({ baudRate: 115200 });
    } 
    catch (error) {
        alert("打开串口失败："+error)
    }

    if (port.value && port.value.readable){

        serialColor.value = "background-color:green;width:30px;height:30px";
    }
    else
    {
        serialColor.value = "background-color:red;width:30px;height:30px";
    }

    await readPort();
};

//关闭串口
const closePort = () => {

    if (reader.value) 
    {
        reader.value.cancel();
    }

    if (port.value) 
    {
        port.value.close();
    }
    
    if (port.value && port.value.readable)
    {
        serialColor.value = "background-color:green;width:30px;height:30px";
    }
    else
    {
        serialColor.value = "background-color:red;width:30px;height:30px";
    }
};

//读取串口
const readPort = async () => {
    textSN.value = "";
    if (port.value && port.value.readable) {

        reader.value = port.value.readable.getReader();
        try {
            var flag = true
            while (true) 
            {

                const { value, done } = await reader.value.read();
                if (done) 
                {
                    textSN.value = value;
                    break;
                }

                for (let i = 0; i < value.length; i++) 
                {
                    if(!flag)
                    {
                        flag = true
                        textSN.value = ''
                    }
                    textSN.value += String.fromCharCode(value[i]);
                    if (value[i] === 13) 
                    {
                        flag = false
                        // 扫码完成
                        textSN.value = textSN.value.replace('\r','').replace('\n', '').trim()

                        virtualSN.value = textSN.value
                        if(selectedMessage.value.LineCode == null || selectedMessage.value.LineCode == '') 
                        {
                            SNMessage.value = "无效扫码,请选择产线"
                        } 
                        else if(selectedMessage.value.StationCode == null || selectedMessage.value.StationCode == '')
                        {
                            SNMessage.value = "无效扫码,请选择工位"
                        } 
                        else{
                            //处理手动扫码
                            if(virtualSN.value != null && virtualSN.value != '') {
                                if(!ScanPattern.value){
                                    request({
                                    url: 'api/RepairRecord/GetSingleRepairData',
                                    method: 'post',
                                    data: {
                                        'LineCode':selectedMessage.value.LineCode,
                                        'StationCode':selectedMessage.value.StationCode,
                                        'TZMaterialCode': virtualSN.value   //电机号
                                    }
                                }).then(res => {
                                    stateInfo.AllBindings = res.RepairMaterialInfos,
                                    OldSN.value = res.SN,
                                    flushUI(selectedMessage.value.LineCode,selectedMessage.value.StationCode)
                                })
                                }
                                else{
                                    request({
                                    url: 'api/RepairRecord/LooseSingleMaterial',
                                    method: 'post',
                                    data: {
                                        'LineCode':selectedMessage.value.LineCode,
                                        'StationCode':selectedMessage.value.StationCode,
                                        'TZMaterialCode': virtualSN.value   //电机号
                                    }
                                }).then(res => {
                                    stateInfo.AllBindings = res.RepairMaterialInfos,
                                    OldSN.value = res.SN,
                                    flushUI(selectedMessage.value.LineCode,selectedMessage.value.StationCode)
                                })
                                }
                                
                            }
                        } 
                    }
                }
            }

        } 
        catch (error) 
        {
            console.error(error);
        } 
        finally 
        {
            if (reader.value) {
                reader.value.releaseLock();
            }
        }
    }
};

</script>

<style scoped lang="scss">
.optimized-card {
    padding: 24px;
    border-radius: 12px;
}

.header-section {
    padding: 16px;
    background: #2c7ed1;
    border-radius: 8px;
    margin-bottom: 24px;

    .station-info {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 24px;
        align-items: center;
    }

    .info-item {
        display: flex;
        align-items: center;
        gap: 8px;

        .info-label {
            font-weight: 500;
            color: #121313;
        }

        .info-input {
            width: 200px;
        }

        .station-tag {
            background: #e6f7ff;
            color: #1890ff;
            padding: 4px 12px;
            border-radius: 4px;
            font-weight: 500;
        }
    }

    .serial-control {
        display: flex;
        align-items: center;
        gap: 12px;

        .status-indicator {
            width: 24px;
            height: 24px;
            border-radius: 50%;
            padding: 0;
            border: 2px solid #fff;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
    }
}

.scan-section {
     
    background: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.05);

    .scan-form {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 24px;
        margin-top: 10px;
         
        align-items: flex-start;
    }

    .scan-input {
        width: 100%;
    }

    .sn-display {
        margin-top: 16px;
        font-size: 18px;
        color: #303133;
        font-weight: 600;
        padding: 12px;
        background: #f6ffed;
        border-radius: 4px;
    }
}

.custom-divider {
    margin: 28px 0;
}

.main-content {
    display: flex;
    gap: 24px;
    min-height: 500px;

    .vertical-divider {
        height: auto;
        margin: 0 24px;
    }
}

.material-section {
    flex: 1;
    background: #fff;
    padding: 16px;
    border-radius: 8px;

    .enhanced-table {
        width: 100%;
        border-collapse: collapse;

        th, td {
            padding: 12px;
            border: 1px solid #ebeef5;
            text-align: center;
        }

        th {
            background: #f5f7fa;
            color: #303133;
            font-weight: 600;
        }

        tbody tr:hover {
            background-color: #fafafa;
        }

        tbody tr:nth-child(even) {
            background-color: #f8f9fa;
        }
    }

    .action-buttons {
        margin-top: 20px;
        display: flex;
        gap: 12px;
        justify-content: flex-end;

        .action-btn {
            padding: 10px 24px;
        }
    }
}

.log-section {
    flex: 0.8;
    background: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.05);

    .log-title {
        color: #303133;
        text-align: center;
        margin-bottom: 16px;
    }

    .log-list {
        max-height: 400px;
        overflow-y: auto;
        padding: 0;
        margin: 0;

        li {
            padding: 12px;
            margin-bottom: 8px;
            border-radius: 4px;
            background: #f8f9fa;
            list-style-type: none;

            &.error-log {
                background: #fff1f0;
                color: #f5222d;
            }
        }
    }
}
</style>




